/*
 * @Desc: 简单的操作界面，包括设置以太网通信参数，进行设备连接控制，发送各种读取命令，写定值等数据到保护设备
 */

#ifndef NZ103Client_H
#define NZ103Client_H

#define TIME_GETDATA_NZ 6000       // 用户点击读取后获取定值信息有关的耗时

#include <QWidget>
#include <QMessageBox>
#include "utils.h"
#include "NZparser.h"
#include "packet.h"
#include "PacketConstructer.h"
#include "PanelBill.h"
#include "NZConnection.h"
#include <QTimer>
#include "CommBase.h"

namespace Ui {
class NZ103Client;
}

// 目标 UDP 端口1032，目标 IP 地址 192.168.0.123 ， 本机TCP 端口 1048， 主站需要实现一个udp客户端和一个tcp服务端
//UDP报文由主站（监控/远动）发送，各子站（保护/测控装置）接收，主要包括主站在线信息和对时信息。UDP报文长度为41字节，子站侧接收程序使用1032（408H）的UDP端口号。
class NZ103Client : public QWidget, public CommBase
{
    Q_OBJECT

public:
    explicit NZ103Client(QWidget *parent = nullptr);
    virtual ~NZ103Client();

    // 外部接口部分
    void connectDevice(QString devAddr, QString devPort, QString localAddr, QString localPort) override;
    void readDeviceAll() override;
    void showTable() override;
    void getAllBillInfo(QMap<QString, BillTableStruct> &tablesInfo) override;     //获取解析完的结果全部
    void disConnectDevice() override;
    void setBillGroup(QStringList& ) override;  // 基本上可以不用这个接口，通过读取全部租标题信息的方式确认定值组号即可
    QStringList getErrorLog() override;

signals:
    void updateServer(QString,int);
    void updateClients(QString,int);
    void disconnected(int);
    void updateBillNames(QStringList);     // 在点击展示表格的时候发送更新定值名称
    void sig_newsRecv(QByteArray);

    // 改到 parser 层发出，使用多线程方式 ---2021.05.27
    void signal_parseFinished(QStringList,int);           // parser层解析完后通知 table更新数据
    void sig_getTitleInfoFinished();
    void sig_getBillAreaFinished(QString);     // 在读取完定值区号后选择当前定值区号
    void sig_sureBillAreaFinished();

    void sig_parserThread(int type, QByteArray);

private slots:
     // udp
    void slot_pushButtonSendUdpMsg_clicked();
    void slot_UdpSocketRecv(QByteArray, QString, QString);
    void on_pushButtonClearRecv_clicked();

    // tcp
    void slot_pushButtonStartTcpServer_clicked();         // 开启tcp服务
    void slot_pushButtonStopTcpServer_clicked();          // 停止 tcp 服务
    void slot_newConnected(QString);                           // 新的客户端连接进来
    void slot_pushButtonSendTcpMsg_clicked();             // 服务端发送消息给客户端


    //void slot_tcpDataReceived();                        // tcp数据接受
    void slot_readData();                               // 读取数据
    void slot_readTcpData(QByteArray);
    void slot_tcpDisconnect();

    void slot_pushButtonClearTcpRecv_clicked();

    void slot_pushButtonSendCMD_clicked();

    void slot_pushButtonShowTable_clicked();

    void slot_updateBillNames();

    void slot_newsParse(QByteArray);             //解析收到的新消息进行分类解析,

    void slot_pushButtonGetModifiedValues_clicked();        // 获取修改后的定值数据序列

//    void on_pushButtonSetIPsPorts_clicked();        //从界面配置通信参数

    void slot_updateUiAsSend(QString);

    void slot_pushButtonReadAll_clicked();    // 改成手动自定义，手动连接

    void slot_readAllTitles();

    void slot_setCanReadBillInfo();     // 置位可以读取定值组信息


    void slot_selectBillArea(QString);         // 选择定值区

    void slot_readBillGroupInfo();

    void slot_getBillInfo();

private:
    // 发送数据到设备，通过调用私有成员 Server 对象的接口来实现
    void sendCmdToDevice(const QString msg);

    // 从设备连接socket中获取数据，通过调用私有成员 Server 对象的接口来实现
    QString getReplyFromDevice();

    void readBillArea();
    void selectBillArea(QString billArea);
    void readBillInfoes();         // 读取定值具体信息

private:
    QString m_connectionInfo;  // 当前连接到服务的保护ip port信息

    Ui::NZ103Client *ui;
    // 把 ES 层进行分层处理
    NZConnection *m_server;            // 通信服务
    PacketConstructer *m_constructer;       // 报文构造工具
    NZParser *m_parser;             // 报文对象解析工具
    PanelBill *m_panelBill;         // 信息显示

    //QUdpSocket *m_UdpClientSocket;        // 主站为udp客户端，保护设备为udp服务端，主站向设备1032端口发送udp报文，告诉保护主站的ip地址

    // 设备连接前的1032端口地址广播，让保护设备连接到主站建立tcp连接

    QString m_rii = "00";  // 返回信息表示符

    QByteArrayList m_recvList;

    QTimer m_readTitleTimer;    // 读标题定时器
    int m_readTitleLimtCount;   // 设置尝试读取标题的最大次数

//    bool m_canReadBillInfo = false;       // 是否可以读取定值组信息状态， 当获取到标题信息后 true

//    QString m_currentBillArea;  // 当前定值区号

    QStringList m_errorList;

    QMap<QString, BillTableStruct> m_tablesInfo;        // table 信息

    QTimer m_timerGetParseResult;   // 延迟6s（预计需要耗时）， 单次触发， 在用户点击读取后启动， 超时就初始化m_tablesInfo

    QThread *m_parserThread;
};

#endif // NZ103Client_H
